package org.ee.system.service;

import org.ee.core.api.PageResult;
import org.ee.core.security.UserPrincipal;
import org.ee.core.util.GuavaUtil;
import org.ee.core.util.SecurityUtil;
import org.ee.system.domain.*;
import org.ee.system.dto.UserDto;
import org.ee.system.reository.OrganizationRepository;
import org.ee.system.reository.RoleRepository;
import org.ee.system.reository.UserRepository;
import org.ee.system.reository.UserRoleRepository;
import org.ee.system.vo.UserInfoVo;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @Author jokr
 * @Date 2025/8/20 下午3:39
 */
@Service
public class UserService  {
    private final UserRepository userRepository;
    private final OrganizationRepository organizationRepository;
    private final PasswordEncoder passwordEncoder;
    private final RoleRepository roleRepository;
    private final UserRoleRepository userRoleRepository;


    public UserService(UserRepository userRepository, OrganizationRepository organizationRepository,
                       PasswordEncoder passwordEncoder, RoleRepository roleRepository, UserRoleRepository userRoleRepository) {
        this.userRepository = userRepository;
        this.organizationRepository = organizationRepository;
        this.passwordEncoder = passwordEncoder;
        this.roleRepository = roleRepository;
        this.userRoleRepository = userRoleRepository;
    }

    /**
     * 注册用户
     *
     * @param user
     * @return
     */
    @Transactional
    public UserInfo register(UserInfo user) {
        Optional<UserInfo> existingUser = userRepository.findByUserName(user.getUserName());

        if (existingUser.isPresent()) {
            throw new RuntimeException("用户已存在");
        }
        String encryptedPassword = passwordEncoder.encode(user.getUserPwd());
        UserInfo model = new UserInfo();
        model.setUserName(user.getUserName());
        model.setUserPwd(encryptedPassword);
        return userRepository.save(model);
    }

    /**
     * 获取用户信息
     *
     * @param
     * @return
     */
    public UserInfoVo getCurrentUserInfo() {
        Optional<UserPrincipal> user = SecurityUtil.getCurrentUser();
        if(user.isPresent()) {
            UserPrincipal userPrincipal = user.get();
            UserInfo model = userRepository.findById(userPrincipal.getCurrentUserId()).orElse(null);
            UserInfoVo vo = null;
            if (Objects.nonNull(model)) {
                vo = new UserInfoVo();
                BeanUtils.copyProperties(model, vo);
                List<String> buttons = GuavaUtil.createEmptyList();
                buttons.add("B_CODE1");
                buttons.add("B_CODE2");
                buttons.add("B_CODE3");
                List<String> roles = GuavaUtil.createEmptyList();
                roles.add("R_SUPER");
                vo.setRoles(roles);
                vo.setButtons(buttons);
            }
            return vo;
        }
       return null;
    }

    /**
     * 获取用户
     *
     * @param id
     * @return
     */
    public UserInfo getSysUserById(Long id) {
        return userRepository.findById(id).orElse(null);
    }


    /**
     * 分页查询
     * @param page
     * @param size
     * @return
     */
    public PageResult<UserInfoVo> getSysUserList(int page, int size) {
        Pageable pageable= PageRequest.of(page-1,size);
        Page<UserInfo> users = userRepository.findAllWithRoles(pageable);

        PageResult<UserInfoVo> pageResult = new PageResult<>(
                users.getTotalElements(),
                users.getSize(),
                users.getNumber()+1,
                users.getContent().stream().map(user->{
                   UserInfoVo vo = new UserInfoVo();
                   BeanUtils.copyProperties(user,vo);
                   //映射角色
                    List<String> roleNames=user.getUserRoles().stream()
                            .map(userRole -> userRole.getRole().getName()).toList();
                    List<Long> roleIds=user.getUserRoles().stream().map(userRole -> userRole.getRole().getId()).toList();
                    vo.setRoles(roleNames);
                    vo.setRoleIds(roleIds);
                    vo.setRole(roleIds);
                   return vo;
                }).toList());
        return pageResult;
    }

    /**
     * 添加用户
     * @param userDto
     */
    @Transactional
    public void add(UserDto userDto){
        if(userDto!=null){
            Optional<UserInfo> user = userRepository.findByUserName(userDto.getUserName());
            if(user.isPresent()){
                throw new RuntimeException("用户已存在");
            }
            UserInfo model = new UserInfo();
            BeanUtils.copyProperties(userDto,model);
            //设置组织
            if(userDto.getOrganizationId()!=null){
                Organization organization = organizationRepository.findById(userDto.getOrganizationId())
                        .orElseThrow(()->new RuntimeException("组织架构不存在"));
            }
            model.setUserPwd(passwordEncoder.encode("123456"));

            //先保存用户
            userRepository.save(model);
            //关联关系处理
            if(userDto.getRole()!=null&& !userDto.getRole().isEmpty()){
                Set<UserRole> userRoles = new HashSet<>();
                for(Long roleId : userDto.getRole()) {
                    Role role=roleRepository.findById(roleId)
                            .orElseThrow(()->new RuntimeException("角色不存在："+roleId));
                    UserRoleId userRoleId=new UserRoleId();
                    userRoleId.setRoleId(roleId);
                    userRoleId.setUserId(model.getId());
                    UserRole userRole=new UserRole();
                    userRole.setSysUserRoleId(userRoleId);
                    userRole.setUser(model);
                    userRole.setRole(role);
                    userRoles.add(userRole);
                }
                userRoleRepository.saveAll(userRoles);
            }
        }
    }

    /**
     * 删除用户
     * @param id
     */
    @Transactional
    public void delete(Long id){
        userRepository.deleteById(id);
        userRoleRepository.deleteByUserId(id);
    }
}
